﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FreightSoft.Models;
using FreightSoft.Classes;

namespace FreightSoft.Controllers
{
    public class ShipmentLineController : Controller
    {
        private Entities db = new Entities();        
        //
        // GET: /ShipmentLine/

        public ActionResult Index()
        {
            var shipmentlines = db.SHIPMENTLINEs.Include(s => s.SHIPMENT);
            return View(shipmentlines.ToList());
        }

        //
        // GET: /ShipmentLine/Details/5

        public ActionResult Details(decimal id = 0)
        {
            SHIPMENTLINE shipmentline = db.SHIPMENTLINEs.Find(id);
            if (shipmentline == null)
            {
                return HttpNotFound();
            }
            return View(shipmentline);
        }

        //
        // GET: /ShipmentLine/Create

        public ActionResult Create()
        {
            ViewBag.SHIPMENTID = new SelectList(db.SHIPMENTs, "SHIPMENTID", "ORIGINPORT");
            return View();
        }

        //
        // POST: /ShipmentLine/Create

        [HttpPost]
        public ActionResult Create(SHIPMENTLINE shipmentline)
        {
            if (ModelState.IsValid)
            {
                db.SHIPMENTLINEs.Add(shipmentline);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.SHIPMENTID = new SelectList(db.SHIPMENTs, "SHIPMENTID", "ORIGINPORT", shipmentline.SHIPMENTID);
            return View(shipmentline);
        }

        //
        // GET: /ShipmentLine/Edit/5

        public ActionResult Edit(decimal id = 0)
        {
            SHIPMENTLINE shipmentline = db.SHIPMENTLINEs.Find(id);
            if (shipmentline == null)
            {
                return HttpNotFound();
            }
            ViewBag.SHIPMENTID = new SelectList(db.SHIPMENTs, "SHIPMENTID", "ORIGINPORT", shipmentline.SHIPMENTID);
            return View(shipmentline);
        }

        //
        // POST: /ShipmentLine/Edit/5

        [HttpPost]
        public ActionResult Edit(SHIPMENTLINE shipmentline)
        {
            if (ModelState.IsValid)
            {
                db.Entry(shipmentline).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.SHIPMENTID = new SelectList(db.SHIPMENTs, "SHIPMENTID", "ORIGINPORT", shipmentline.SHIPMENTID);
            return View(shipmentline);
        }

        //
        // GET: /ShipmentLine/Delete/5

        public ActionResult Delete(decimal id = 0)
        {
            SHIPMENTLINE shipmentline = db.SHIPMENTLINEs.Find(id);
            if (shipmentline == null)
            {
                return HttpNotFound();
            }
            return View(shipmentline);
        }

        //
        // POST: /ShipmentLine/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(decimal id)
        {
            SHIPMENTLINE shipmentline = db.SHIPMENTLINEs.Find(id);
            db.SHIPMENTLINEs.Remove(shipmentline);
            db.SaveChanges();
            return RedirectToAction("Index");

        }
        public ActionResult AddOrders(decimal shipment_id)
        {
            ViewBag.SHIPMENT_ID = shipment_id;
            var model = TempData["Order_list"] as List<CUSTOMER_ORDER>;
            if (model.Count() <= 0)
            {
                TempData["error"] = "No orders to be added to the Shipment!";
            }
            return View(model.ToList());
        }

        public ActionResult AddOrder(decimal shipment_id, decimal order_id, decimal customer_id)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    SHIPMENTLINE shipment_line = new SHIPMENTLINE();
                    shipment_line.SHIPMENTID = shipment_id;
                    shipment_line.CUSTOMERID = customer_id;
                    shipment_line.ORDERID = order_id;
                    shipment_line.STATUS = "Planned";
                    // update volume and weight with Order information
                    shipment_line.VOLUME = GetOrderVolume(order_id);
                    shipment_line.WEIGHT = GetOrderWeight(order_id);
                    // this is the date the order is added to the shipment
                    shipment_line.S2 = System.DateTime.Now.ToString();

                    if (!shipment_line.VOLUME.HasValue)
                    {
                        shipment_line.VOLUME = 0;
                    }
                    if (!shipment_line.WEIGHT.HasValue)
                    {
                        shipment_line.WEIGHT = 0;
                    }
                    db.SHIPMENTLINEs.Add(shipment_line);
                    
                    db.SaveChanges();
                    
                    // Update total volume and weight of the shipment
                    UpdateShipmentVolumeWeight(shipment_id, order_id);


                    var shipmentLineNo = db.SHIPMENTLINEs.Max(p => p.SHIPMENTLINENO);
                   
                    //var orders_list = from shipmentlines in db.SHIPMENTLINEs
                    //                  where (shipmentlines.SHIPMENTID == shipment_id) && (shipmentlines.SHIPMENTLINENO == shipmentLineNo)
                    //                 // && (orders.STATUS == "Invoices")
                    //                  select shipmentlines;
                    //var tt = orders_list.ToList();
                    //int no =0;
                    //if (tt.Count() >= 1)
                    //{
                    //    no = (int) tt[0].TRACKINGNO;
                    //}
                    int orderId = (int)order_id;
                    // should update CUstomer order status as well.
                    ReadyForShip(orderId);

                    ViewBag.SHIPMENT_ID = shipment_id;
                    //ViewBag.TRACKINGNO = no;
                    //var rr = shipment_line.TRACKINGNO;
                    SHIPMENT shipment = db.SHIPMENTs.Find(shipment_id);

                    //SHIPMENT record = db.SHIPMENTs.Find(shipment_id);

                   // List<CUSTOMER_ORDER> order_list = GetOrderForShipment(record.ORIGINPORT, record.DESTINATIONPORT);
                    //return View(shipments.ToList());
                    ViewBag.SHIPMENT_ID = shipment_id;
                    //TempData["Order_list"] = order_list.ToList();
                    
                    List<CUSTOMER_ORDER> orders = GetOrderForShipment(shipment_id, shipment.ORIGINPORT, shipment.DESTINATIONPORT);
                    TempData["Order_list"] = orders.ToList();
                    return RedirectToAction("AddOrders", new { shipment_id = shipment_id });
                    //return RedirectToAction("AddOrders", orders.ToList());
                }
                return View("Index");
            }
            catch (System.Data.DataException e)
            {
                ModelState.AddModelError("", "");
            }
            return View("Index");

        }

        public ActionResult RemoveOrder(decimal shipment_id, decimal order_id)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    SHIPMENT shipment = db.SHIPMENTs.Find(shipment_id);
                        var ordDetailQuery =
                        from record in db.SHIPMENTLINEs
                        where record.ORDERID == order_id
                        select record;

                        foreach (var selectedDetail in ordDetailQuery)
                        {
                            shipment.VOLUME = shipment.VOLUME - selectedDetail.VOLUME;
                            shipment.WEIGHT = shipment.WEIGHT - selectedDetail.WEIGHT;
                            db.SaveChanges();

                            // change the status back
                            CUSTOMER_ORDER order = db.CUSTOMER_ORDER.Find(selectedDetail.ORDERID);
                            order.STATUS = "Invoiced";
                            db.SaveChanges();

                            db.SHIPMENTLINEs.Remove(selectedDetail);
                            db.SaveChanges();
                        }
                    
                    
                   // List<CUSTOMER_ORDER> orders = GetOrderForShipment(shipment_id, shipment.ORIGINPORT, shipment.DESTINATIONPORT);
                   // return RedirectToAction("AddOrders", orders.ToList());
                        return RedirectToAction("Details", "Shipment", new { id = shipment_id });
                        //return View("Index");
                }
                return View("Index");
            }
            catch (System.Data.DataException)
            {
                ModelState.AddModelError("", "");
            }
            return View("Index");

        }

        public void ReadyForShip(int id)
        {
            OzekiSMS sms = new OzekiSMS();
            CUSTOMER_ORDER order = db.CUSTOMER_ORDER.Find(id);
            order.STATUS = "ReadyToShip";
            db.SaveChanges();
            // need to modify to send message properly // tracking_No or Order_no ???
            //sms.SendSMS(order.CUSTOMER_ID.ToString(), ("Your order is Ready for Shipping. Your Order Tracking No is : " + order.ORDER_ID.ToString()));
           // db.OZEKIMESSAGEOUTs.Add(new OZEKIMESSAGEOUT { MSG = "Your order is Ready for Shipping. Your Tracking No is : ", SENDER = "0094727205458", RECEIVER = "0094715205458", MSGTYPE = "SMS:TEXT" });
        }
        // get order records to attach to a particular shipment
        protected List<CUSTOMER_ORDER> GetOrderForShipment(decimal shipment_id, string origin_port, string dest_port)
        {
            SHIPMENT shipment = db.SHIPMENTs.Find(shipment_id);
            var orders_list = from orders in db.CUSTOMER_ORDER
                              where (orders.SOURCE == origin_port) && (orders.DESTINATION == dest_port)
                              && (orders.STATUS == "Invoiced") 
                              && (shipment.PLANNED_DELIVERY_DATE <= orders.WANTED_DELIVERY_DATE)
                              select orders;
            return orders_list.ToList();
        }
        public ActionResult ViewShipmentLines(decimal? shipment_id)
        {
            var shipment_lines = db.SHIPMENTs.Find(shipment_id).SHIPMENTLINEs.ToList();
            //var shipments = db.SHIPMENTs.Where(s => s.SCHEDULEID == schedule_id).ToList();
            return View(shipment_lines);
        }

        public void UpdateShipmentVolumeWeight(decimal shipment_id, decimal order_id)
        {
           // SHIPMENT record = db.SHIPMENTs.Find(shipment_id);
            var shipment_lines = db.SHIPMENTLINEs.Where(p => p.SHIPMENTID == shipment_id);
            SHIPMENT record = db.SHIPMENTs.Find(shipment_id);
            decimal volume = 0;
            decimal weight = 0;
            foreach (var i in shipment_lines)
            {
                volume += (decimal) i.VOLUME;
                weight += (decimal) i.WEIGHT;
            }
            record.VOLUME = volume;
            record.WEIGHT = weight;
            //record.VOLUME += GetOrderVolume(order_id);
            //record.WEIGHT += GetOrderWeight(order_id);
            ////db.SHIPMENTs.
            db.SaveChanges();
            

        }

        public decimal GetOrderWeight(decimal order_id)
        {
            var orderlines = db.ORDER_LINE.Where(p => p.ORDER_ID == order_id);
            //decimal volume = 0;
            decimal weight = 0;
            foreach (var i in orderlines)
            {
                //volume += i.PART.VOLUME;
                weight += (i.PART.WEIGHT * i.QUANTITY);
            }
            return weight;

        }
        public decimal GetOrderVolume(decimal order_id)
        {
            var orderlines = db.ORDER_LINE.Where(p => p.ORDER_ID == order_id);
            decimal volume = 0;
            //decimal weight = 0;
            foreach (var i in orderlines)
            {
                volume += (i.PART.VOLUME * i.QUANTITY);
                //weight += i.PART.WEIGHT;
            }
            return volume;
        }



        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}